﻿using PushEmail.Common;
using PushEmail.Common.Logging;
using PushEmail.Global;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace PushEmail
{
    public class CollectionHelper
    {
        // 得到ItemCollection中要插入的位置
        public static int GetInsertIndexForItemCollection(EmailItemViewModel emailItem, ObservableCollection<EmailItemViewModel> collection)
        {
            if (collection.Count == 0) return 0;

            foreach (var item in collection)
            {
                if (DateTime.Compare(emailItem.ReceiveTime, item.ReceiveTime) >= 0)
                {
                    return collection.IndexOf(item);
                }
            }

            return collection.Count;
        }

        // 得到HeaderCollection中要插入的位置
        public static int GetInsertIndexForHeaderCollection(EmailItemViewModel emailItem,ObservableCollection<EmailItemViewModel> collection)
        {
            if (collection.Count == 0) return 0;

            var header = collection.FirstOrDefault(i => i.Name == emailItem.Name && !i.IsEmail);
            int headerIndex = collection.IndexOf(header);

            if(collection.Count(i=>i.Name==header.Name && i.IsEmail)==0)
                return headerIndex +1;

            int index = headerIndex + 1;

            for (int i = headerIndex + 1; i < collection.Count; i++)
            {

                if (collection[i].Name != header.Name) break;
                if (DateTime.Compare(emailItem.ReceiveTime, collection[i].ReceiveTime) >= 0)
                {
                    return collection.IndexOf(collection[i]);
                }

                index++;
            }

            return index;
        }

        /*
         * \fn DeleteEmail(EMailTitle title)
         * \brief Delete an email,it and also delete the email from database.
         * \param title Email title to be deleted
         */
        static public bool DeleteEmail(EmailItemViewModel title)
        {
            try
            {
                return PEDBManager.Instance().peDataModel.DeleteMail(title.EmailContext);
            }
            catch (Exception e)
            {
                DefaultLogger.Log.LogDebug(e.ToString());

                return false;
            }
        }

        public static void UpdateEmailForOtherEmailCollection(Email mail)
        {
            EmailItemViewModel vm = ConverterToEmailItemViewModel.ConverterToEmailItemVM(mail);
            if (global.inboxEmails.OtherItemsList.Any(e => e.EmailId == vm.EmailContext.emailId))
            {
                var emailItem = global.inboxEmails.OtherItemsList.SingleOrDefault(e => e.EmailId == vm.EmailId);
                global.inboxEmails.OtherItemsList[global.inboxEmails.OtherItemsList.IndexOf(emailItem)] = vm;
            }

            if (global.inboxEmails.OtherEmailItems.Any(e => e.EmailId == vm.EmailContext.emailId))
            {
                var emailItem = global.inboxEmails.OtherEmailItems.SingleOrDefault(e => e.EmailId == vm.EmailId);
                global.inboxEmails.OtherEmailItems[global.inboxEmails.OtherEmailItems.IndexOf(emailItem)] = vm;
            }
        }

        public static void AddEmailToEditEmailCollection(Email mail, EmailGroupType type, Folder folder)
        {
            EmailItemViewModel vm = ConverterToEmailItemViewModel.ConverterToEmailItemVM(mail);
            vm.ContextMenuFavVisibility = Visibility.Collapsed;
            vm.ContextMenuReadVisibility = Visibility.Collapsed;
            vm.IsUnread = false;
            vm.IsReplied = false;
            vm.Sender = vm.EmailContext.toAddress;
            vm.GroupType = type;
            vm.StarFlag = null;

            // 如果没有的话就增加到集合，如果有的话，就更新
            if (!global.inboxEmails.OtherItemsList.Any(e => e.EmailId == vm.EmailContext.emailId))
            {
                global.inboxEmails.OtherItemsList.Add(vm);
            }
            else
            {
                var emailItem = global.inboxEmails.OtherItemsList.SingleOrDefault(e => e.EmailId == vm.EmailId);
                global.inboxEmails.OtherItemsList[global.inboxEmails.OtherItemsList.IndexOf(emailItem)] = vm;
            }

            // 如果没有的话就增加到集合，如果有的话，就更新。
            if (!global.inboxEmails.OtherEmailItems.Any(e => e.EmailId == vm.EmailContext.emailId))
            {
                int index = CollectionHelper.GetInsertIndexForItemCollection(vm, global.inboxEmails.OtherEmailItems);
                global.inboxEmails.OtherEmailItems.Insert(index, vm); 
            }
            else
            {
                var emailItem = global.inboxEmails.OtherEmailItems.SingleOrDefault(e => e.EmailId == vm.EmailId);
                global.inboxEmails.OtherEmailItems[global.inboxEmails.OtherEmailItems.IndexOf(emailItem)] = vm;
            }

            
            if (folder != null)
            {
                FolderType folderType = PEDBManager.Instance().peDataModel.GetFolderTypeById(mail.folderId);
                if (folderType == (FolderType)folder.type)
                {
                    if (!global.inboxEmails.OtherHeaderItems.Any(e => e.EmailId == vm.EmailContext.emailId))
                    {
                        if (!ExistHeader(vm.Name, global.inboxEmails.OtherHeaderItems))
                        {
                            InsertHeader(vm.Name, vm.GroupType,true,false, global.inboxEmails.OtherHeaderItems);
                        }
                        int headerIndex = CollectionHelper.GetInsertIndexForHeaderCollection(vm, global.inboxEmails.OtherHeaderItems);
                        global.inboxEmails.OtherHeaderItems.Insert(headerIndex, vm);
                    }
                    else
                    {
                        var emailItemForHeader = global.inboxEmails.OtherHeaderItems.SingleOrDefault(e => e.EmailId == vm.EmailId);
                        if (emailItemForHeader != null)
                        {
                            global.inboxEmails.OtherHeaderItems[global.inboxEmails.OtherHeaderItems.IndexOf(emailItemForHeader)] = vm;
                        }
                    }

                }
                else
                {
                    var emailItemForHeader = global.inboxEmails.OtherHeaderItems.SingleOrDefault(e => e.EmailId == vm.EmailId);
                    if (emailItemForHeader != null)
                    {
                        global.inboxEmails.OtherHeaderItems.Remove(emailItemForHeader);

                        List<uint> folderIds = PEDBManager.Instance().peDataModel.GetFolderIdsByFolderType(folderType);

                        if (!global.inboxEmails.OtherEmailItems.Any(i => i.EmailContext != null && i.Name == emailItemForHeader.Name && i.AccountId == emailItemForHeader.AccountId && folderIds.Contains(i.EmailContext.folderId)))
                        {
                            var header = global.inboxEmails.OtherHeaderItems.SingleOrDefault(h => h.Name == emailItemForHeader.Name);
                            if (header != null)
                            {
                                header.ShowVisibility = Visibility.Collapsed;
                            }
                        }
                    }
                }
 
            }
        }

        public static void InsertHeader(string headerName, EmailGroupType groupType, bool IsExpanded,bool IsDateChecked, ObservableCollection<EmailItemViewModel> headerCollection)
        {
            var headerList = headerCollection.Where(h => !h.IsEmail).ToList();

            EmailItemViewModel headerItemViewModel = new EmailItemViewModel
            {
                Name = headerName,
                GroupType = groupType,
                HeadVisibility = Visibility.Visible,
                EmailVisibility = Visibility.Collapsed,
                InboxEmailDateMultiselectBoxVisible = Visibility.Collapsed,
                IsExpanded = IsExpanded,
                IsDateChecked = IsDateChecked,
                IsEmail = false,
                HeaderOrder = CollectionHelper.GetHeaderOrder(headerName),
            };

            if (headerList.Count() < 1)
            {
                headerCollection.Add(headerItemViewModel);
                return;
            }

            int index = 0;

            foreach (var item in headerList)
            {
                if (headerItemViewModel.HeaderOrder < item.HeaderOrder)
                {
                    index = headerCollection.IndexOf(item);
                    break;
                }
                else
                {
                    if (item.Equals(headerList.Last()))
                    {
                        index = headerCollection.IndexOf(item) + 1;
                    }
                }
                
            }

            headerCollection.Insert(index, headerItemViewModel);
        }

        public static bool ExistHeader(string name, ObservableCollection<EmailItemViewModel> headerCollection)
        {
            if (headerCollection.Any(h => !h.IsEmail && h.Name == name)) 
                return true;
            else
                return false;
        }

        public static int GetHeaderOrder(string name)
        {
            int HeaderOrder;
            switch (name)
            {
                case "今天":
                    HeaderOrder = 1;
                    break;
                case "昨天":
                    HeaderOrder = 2;
                    break;
                case "前天":
                    HeaderOrder = 3;
                    break;
                case "本周":
                    HeaderOrder = 4;
                    break;
                case "上周":
                    HeaderOrder = 5;
                    break;
                //case TimeSpanAncient:
                default:
                    HeaderOrder = 6;
                    break;
            }

            return HeaderOrder;
        }
    }
}
